package org.fastframework.boot.proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.List;

public class CglibProxy implements MethodInterceptor {
    private Object tar;
    private Method before;
    private Method after;
    private List<Method> tarMethods;

    /**
     * 构造代理对象与执行方法
     *
     * @param tar
     * @param before
     * @param after
     */
    CglibProxy(Object tar, Method before, Method after, List<Method> tarMethods) {
        this.tar = tar;
        this.before = before;
        this.after = after;
        this.tarMethods = tarMethods;
    }

    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object result = null;
        try {
            if (tar != null && before != null && tarMethods.contains(method))
                before.invoke(tar, null);
            result = methodProxy.invokeSuper(object, args);
            if (tar != null && after != null && tarMethods.contains(method))
                after.invoke(tar, null);
        } catch (Exception e) {
            e.printStackTrace();
            // todo 全局异常处理
        }
        return result;
    }

    /**
     * 初始化aop
     *
     * @param object
     * @param befor
     * @param after
     * @return
     */
    public static Object initAop(Object object, Object tar, Method befor, Method after, List<Method> tarMethods) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(object.getClass());
        enhancer.setCallback(new CglibProxy(tar, befor, after, tarMethods));
        return enhancer.create();
    }

}